﻿/*
 * LitePlayer.h
 *
 *  Created on: 2016年3月16日
 *      Author: terry
 */

#ifndef LITEPLAYER_H_
#define LITEPLAYER_H_

#include "MediaFormat.h"
#include "Overlay.h"
#include "VideoWindow.h"
#include "MediaEventSink.h"
#include "MediaPacketSink.h"


namespace av
{


class  LitePlayer
{
public:
	virtual ~LitePlayer() {}

	/**
	 * 打开媒体流
	 * @param url 		媒体源URL
	 * @param params    参数
	 * @return 0 表示成功
	 */
	virtual int open(const char* url, const char* params) =0;

	/**
	 * 关闭媒体流
	 */
	virtual void close() =0;

	/**
	 * 媒体流是否打开
	 * @return true 表示媒体流已经打开就绪
	 */
	virtual bool isOpen() =0;

	/**
	 * 获取媒体URL
	 * @return URL
	 */
	virtual const char* getURL() =0;

	/**
	 * 获取媒体流格式
	 * @param fmt
	 * @return true 表示成功
	 */
	virtual bool getFormat(MediaFormat& fmt) =0;

	/**
	 * 获取媒体流时长，单位为毫秒
	 * @return 媒体流时长，如果是实时流，返回0
	 */
	virtual int getDuration() =0;

	/**
	 * 播放
	 * return 0 表示成功
	 */
	virtual int play() =0;

	virtual int pause() =0;

	virtual void stop() =0;

	/**
	 * 获取播放状态
	 * @return 播放状态，@see StreamState
	 */
	virtual int getState() =0;


	/**
	 * 判断是否可定位
	 * @return true 表示可定位
	 */
	virtual bool seekable() =0;


	/**
	 * 定位到指定时间点
	 * @param offset    时间点，单位为毫秒，不应超过 duration
	 * @return 0 表示成功
	 */
	virtual int seek(int64_t offset) =0;

	/**
	 * 获取当前已播放时长
	 * @return 播放时间，单位为毫秒
	 */
	virtual int64_t getTime() =0;


	/**
	 * 设置播放速度，正常播放速度为 1.0
	 * @param scale 播放速度，取值范围: [1/8, 8]
	 * @return 0 表示成功
	 */
	virtual int setScale(float scale) =0;

	/**
	 * 获取播放速度
	 * @return 播放速度
	 */
	virtual float getScale() =0;

	/**
	 * get current volume
	 * @return [0.0, 1.0]
	 */
	virtual float getVolume() =0;

	/**
	 * 设置音量
	 * @param vol 音量，取值范围为：[0, 1.0]
	 * @return
	 */
	virtual int setVolume(float vol) =0;

	virtual bool isMute() =0;

	/**
	 * 设置静音
	 * @param muted true表示静音， false表示打开声音
	 * @return 0 表示成功
	 */
	virtual int setMute(bool muted) =0;


	virtual bool isFullscreen() =0;

	/**
	 * 设置全屏
	 * @param full 表示全屏
	 * @return 0 表示成功
	 */
	virtual int setFullscreen(bool full) =0;

	/**
	 * 设置视频显示窗口
	 * @param hwnd
	 * @return
	 */
	virtual void setVideoWnd(void* hwnd) =0;

	virtual void setVideoWindow(VideoWindow* window) = 0;

	/**
	 * 设置视频宽高比率
	 * 如果width,height = 0, 保持视频的原始比率
     * 如果width,height < 0, 填充屏幕, 否则适应指定的比率
	 * @param width
	 * @param height
	 * @return 0 on success
	 */
	virtual int setRatio(int width, int height) =0;

	virtual void getRatio(int& width, int& height) =0;

	/**
	 * 设置播放器logo
	 * @param filepath
	 * @return
	 */
	virtual int setImage(const char* filepath) =0;


	/**
	 * 抓图
	 * @param filepath 图片路径
	 * @return 0 表示成功
	 */
	virtual int snap(const char* filepath) =0;


	/**
	 * 设置过滤器, 参考avfilter设置
	 * @param filterString
	 * @return 0 表示成功
	 */
	virtual int setVideoFilter(const char* filterString) =0;


	virtual int addOverlay(int idx, Overlay& osd) =0;

	virtual int removeOverlay(int idx) =0;

	virtual void clearOverlay() =0;

	virtual void setOverlay(const Overlay* osds, size_t size) =0;


	


	/**
	 * 设置媒体流回调
	 * @param pSink 接收未解码媒体包
	 */
	virtual void setPacketSink(MediaPacketSink* pSink) =0;

	/**
	 * 设置事件回调
	 * @param pSink 事件回调
	 */
	virtual void setEventSink(MediaEventSink* pSink) =0;




	virtual int togglePlay() =0;

	virtual int toggleMute() =0;

	virtual int toggleFull() =0;

	/**
	 * 减速播放, 每次减速 STEP_SCALE, 直到最低速度 MIN_SCALE
	 * @return
	 */
	virtual int slow() =0;

	/**
	 * 快速播放, 每次增速 STEP_SCALE, 直到最大速度 MAX_SCALE
	 * @return
	 */
	virtual int fast() =0;


	/**
	 * 开始录像
	 * 在 open 之前设置属性 AutoRecord 为文件名, 播放时自动录像
	 * 不调用 stopRecord 而多次调用 startRecord , 可以实现无缝切换文件
	 * @param  filename  录像文件名称
	 * @return 0 表示成功
	 */
	virtual int startRecord(const char* filename) =0;

	/**
	 * 停止录像
	 */
	virtual void stopRecord() =0;

	/**
	 *  是否在录像中
	 */
	virtual bool isRecording() =0;



    /**
     * 单帧播放
     * @return 0 表示成功
     */
    virtual int step() =0;


    /**
     * 播放下一关键帧
     * @return 0 表示成功
     */
    virtual int nextKeyFrame() =0;


    /**
     * 获取属性
     * @param name  属性名称
     * @param value 属性值
     * @return 长度, <= 0 表示不存在
     */
    virtual size_t getProp(const char* name, char* value, size_t size) =0;

    /**
     * 设置属性
     * @param name 属性名称
     * @param value 属性值
     * @return true 表示成功
     */
    virtual bool setProp(const char* name, const char* value) =0;

    virtual bool existProp(const char* name) =0;

};


class  InputPlayer : public LitePlayer
{
public:
	virtual ~InputPlayer() {}

    virtual int open(const MFormat& fmt) =0;

    virtual bool write(MPacket& pkt) =0;

    virtual void writeEnd() =0;

    virtual void flush() =0;

};


/**
 * 播放器工厂
 */
class DLLEXPORT LitePlayerFactory
{
public:
    LitePlayerFactory()
    {
        startup();
    }

    ~LitePlayerFactory()
    {
        cleanup();
    }

    static bool startup();

    static void cleanup();

    /**
     * 创建播放器
     * @param hwnd
     * @return NULL if failed
     */
    static LitePlayer* create(void* hwnd);

    /**
     * 销毁播放器
     * @param pPlayer
     */
    static void destroy(LitePlayer* pPlayer);

    /**
     * 创建输入播放器
     */
    static InputPlayer* createInputPlayer(void* hwnd);


    /**
     * 获取全局属性
     * @param name	属性名称
     * @param value 属性值
     * @return 长度, <= 0 表示不存在
     */
    static size_t getProp(const char* name, char* value, size_t size);

    /**
     * 设置全局属性
     * @param name	属性名称
     * @param value	属性值
     * @return
     */
    static bool setProp(const char* name, const char* value);

    /**
     * 是否存在属性
     * @param name
     * @return
     */
    static bool existProp(const char* name);

    /**
     * 允许输出日志到文件/控制台
     */
    static void enableLog(const char* filename);

};





} /* namespace av */

#endif /* LITEPLAYER_H_ */
